package com.c2c.handler;

import com.c2c.po.GoodsClassify;
import com.c2c.po.enums.*;
import com.c2c.po.enums.impl.*;
import com.c2c.utils.CodeEnumUtil;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


/* 数据库中的数据类型 */
@MappedJdbcTypes(JdbcType.TINYINT)

/* JAVA的数据类型 */
@MappedTypes({
        CommentsState.class,
        ComplaintsState.class,
        UsersState.class,
        OrdersState.class,
        GoodiesState.class
})
public class CodeEnumTypeHandler<E extends Enum<?> & BaseCodeEnum> extends BaseTypeHandler<BaseCodeEnum> {

    //获取JAVA类
    private Class<E> type;

    //获取子类实现
    public CodeEnumTypeHandler(Class<E> type) {
        if (type == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }
        this.type = type;
    }

    //负责将JAVA类型转换为数据库需要的类型
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, BaseCodeEnum baseCodeEnum, JdbcType jdbcType) throws SQLException {
        preparedStatement.setByte (i, (byte) baseCodeEnum.getCode());
    }
    //负责将数据库中类型转换成JAVA类型
    //String参数   要转换的字段的名称
    //ResultSet  查询出的结果集
    @Override
    public BaseCodeEnum getNullableResult(ResultSet resultSet, String s) throws SQLException {
        int code = resultSet.getInt(s);
        return resultSet.wasNull() ? null : codeOf(code);
    }
    //负责将数据库中类型转换成JAVA类型
    @Override
    public BaseCodeEnum getNullableResult(ResultSet resultSet, int i) throws SQLException {
        int code = resultSet.getInt(i);
        return resultSet.wasNull() ? null : codeOf(code);
    }
    //负责将数据库中类型转换成JAVA类型
    @Override
    public BaseCodeEnum getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        int code = callableStatement.getInt(i);
        return callableStatement.wasNull() ? null : codeOf(code);
    }

    //用从数据库获取到的内容通过此方法进行匹配转换
    private E codeOf(int code) {
        try {
            return CodeEnumUtil.codeOf(type, code);
        } catch (Exception ex) {
            throw new IllegalArgumentException("Cannot convert " + code + " to " + type.getSimpleName() + "by code value.", ex);
        }
    }
}
